home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / internet / amitcp3.0b / src.lha / src / amitcp / net / sana2config.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-08  |  8.7 KB  |  404 lines

  1. RCS_ID_C="$Id: sana2config.c,v 3.2 1994/02/03 19:10:09 ppessi Exp $";
  2. /*
  3.  * Copyright (c) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
  4.  *                    Helsinki University of Technology, Finland.
  5.  *                    All rights reserved.
  6.  *
  7.  * sana2config.c - Configuration parameters for SANA-II network interfaces
  8.  *
  9.  * HISTORY
  10.  * $Log: sana2config.c,v $
  11.  * Revision 3.2  1994/02/03  19:10:09  ppessi
  12.  * Changed the interface database format
  13.  *
  14.  * Revision 3.1  1994/02/03  03:50:38  ppessi
  15.  * Initially tested version
  16.  *
  17.  */
  18.  
  19. #include <conf.h>
  20.  
  21. #include <sys/param.h>
  22. #include <sys/socket.h>
  23. #include <sys/socketvar.h>
  24. #include <net/if.h>
  25. #include <net/if_types.h>
  26. #include <assert.h>
  27.  
  28. #if NS
  29. #error NS is not supported
  30. #endif
  31.  
  32. #include <kern/amiga_includes.h>
  33. #if __SASC
  34. #include <proto/dos.h>
  35. #elif __GNUC__
  36. #include <inline/dos.h>
  37. #else
  38. #error Your compiler is not supported in this release.
  39. #endif
  40.  
  41. #include <netinet/in.h>
  42. #include <devices/sana2.h>
  43. #include <utility/tagitem.h>
  44. #include <net/sana2tags.h>
  45. #include <net/sana2config.h>
  46. #include <net/if_arp.h>
  47. #include <net/if_sana.h>
  48.  
  49. static const char template[] = SSC_TEMPLATE;
  50.  
  51. #define CONFIGLINELEN 1024
  52.  
  53. /*
  54.  * Parse the configuration 
  55.  */
  56. static struct ssconfig *
  57. ssconfig_parse(struct CSource argfile[])
  58. {
  59.   struct ssconfig *config = AllocVec(sizeof(*config), MEMF_CLEAR|MEMF_PUBLIC);
  60.   /*
  61.    * Initialize the RDArgs structure for ReadArgs()
  62.    */
  63.   struct RDArgs *rdargs = config->rdargs;
  64.   
  65.   if (config != NULL) {
  66.     rdargs->RDA_Source = *argfile;
  67.     rdargs->RDA_DAList = NULL;
  68.     rdargs->RDA_Buffer = NULL;
  69.     rdargs->RDA_BufSiz = 0;
  70.     rdargs->RDA_ExtHelp = NULL;
  71.     rdargs->RDA_Flags = RDAF_NOPROMPT;
  72.     
  73.     if (ReadArgs(template, (LONG *)config->args, rdargs)) {
  74.       config->flags |= SSCF_RDARGS;
  75.       return config;
  76.     } else {
  77.       FreeVec(config);
  78.     }
  79.   }
  80.   return NULL;
  81. }
  82.  
  83. /*
  84.  * Free the configuration
  85.  */
  86. void
  87. ssconfig_free(struct ssconfig config[])
  88. {
  89.   if (config->flags & SSCF_RDARGS)
  90.     FreeArgs(config->rdargs);
  91.   FreeVec(config);
  92. }
  93.  
  94. static int
  95. getconfs(BPTR iffh, UBYTE *buf)
  96. {
  97.   LONG i, quoted = 0, escaped = 0;
  98.  
  99.   if (FGets(iffh, buf, CONFIGLINELEN - 1)) {
  100.     for (i = 0; buf[i]; i++) {
  101.       UBYTE c = buf[i];
  102.       if (c == '\n') {
  103.     if (quoted) {
  104.       return ERROR_UNMATCHED_QUOTES;
  105.     }
  106.     if (i > 0 && buf[i - 1] == '+') {
  107.       i--;
  108.       if (i < CONFIGLINELEN - 2) {
  109.         if (FGets(iffh, buf + i, CONFIGLINELEN - 1 - i))
  110.           continue;
  111.         return IoErr();
  112.       }        
  113.       return ERROR_LINE_TOO_LONG;
  114.     }
  115.     return 0;
  116.       } else if (quoted) {
  117.     if (escaped) {
  118.       escaped = 0;
  119.     } else if (c == '*') {
  120.       escaped = 1;
  121.       continue;
  122.     } else if (c == '"') {
  123.       quoted = 0;
  124.     }
  125.       } else if (c == ';' || c == '#') {
  126.     buf[i++] = '\n';
  127.     buf[i] = '\0';
  128.     return 0;
  129.       } else if (escaped) {
  130.     escaped = 0;
  131.       } else if (c == '*') {
  132.     escaped = 1;
  133.       } else if (c == '"') {
  134.     quoted = 1;
  135.       }
  136.     }
  137.     return ERROR_LINE_TOO_LONG;
  138.   }
  139.  
  140.   buf[0] = '\0';
  141.   return IoErr();
  142. }
  143.  
  144. /*
  145.  * Read configuration file 
  146.  */
  147. struct ssconfig *
  148. ssconfig_make(int how, char *unitname, long unit)
  149. {
  150.   LONG ioerr = 0;
  151.   BPTR iffh;
  152.   UBYTE *buf;
  153.   struct ssconfig *ssc = NULL, *ssc_generic = NULL;
  154.   char devname[IFNAMSIZ];
  155.   char *cp;
  156.  
  157.   if (how == SSC_ALIAS) {
  158.     /* Copy the interface name */
  159.     cp = strncpy(devname, unitname, IFNAMSIZ); 
  160.     devname[IFNAMSIZ-1] = '\0';
  161.   
  162.     for (; *cp; cp++)
  163.       if (*cp >= '0' && *cp <= '9')
  164.     break;
  165.     *cp = '\0';
  166.   }
  167. #ifdef COMPAT_AMITCP2
  168.   else if (how == SSC_COMPAT) {
  169.   }
  170. #endif
  171.   else {
  172.     return NULL;
  173.   }
  174.  
  175.   buf = AllocVec(CONFIGLINELEN, MEMF_PUBLIC);
  176.   iffh = Open(_PATH_SANA2CONFIG, MODE_READWRITE);
  177.   if (iffh && buf) {
  178.     BPTR oldinfh = SelectInput(iffh);
  179.     struct CSource arg[1];
  180.  
  181.     /* There is bug in FGets -- the last char is not necessary 0 */
  182.     buf[CONFIGLINELEN - 1] = '\0';
  183.  
  184.     while ((ioerr = getconfs(iffh, buf)) == 0) {
  185.       struct ssconfig *s; 
  186.       if (buf[0] == '\n')
  187.     continue;
  188.       if (buf[0] == '\0')
  189.     break;
  190.  
  191.       arg->CS_Buffer = buf;
  192.       arg->CS_Length = strlen(buf);
  193.       arg->CS_CurChr = 0;
  194.       if (s = ssconfig_parse(arg)) {
  195.     if (how == SSC_ALIAS) {
  196.       s->unit = unit;
  197.       if (strcmp(s->args->a_name, unitname) == 0) {
  198.         ssc = s;
  199.         break;
  200.       } else if (ssc_generic == NULL && 
  201.              strcmp(s->args->a_name, devname) == 0) {
  202.         ssc_generic = s;
  203.         continue;
  204.       }
  205.     } 
  206. #ifdef COMPAT_AMITCP2
  207.     else if (how == SSC_COMPAT) {
  208.       /*
  209.        * Try to find interface with matching exec device and unit
  210.        */
  211.       if (strcmp(FilePart(s->args->a_dev), FilePart(unitname)) == 0 &&
  212.           (s->args->a_unit == NULL || *s->args->a_unit == unit)) {
  213.         /* Copy the devname */
  214.         cp = strncpy(devname,  s->args->a_name, IFNAMSIZ); 
  215.         devname[IFNAMSIZ-1] = '\0';
  216.   
  217.         for (; *cp; cp++)
  218.           if (*cp >= '0' && *cp <= '9')
  219.         break;
  220.  
  221.         if (*cp) { 
  222.           /* an interface with unit number, eg. "slip0" */
  223.           int ifunit = *cp - '0';
  224.           *cp++ = '\0';
  225.  
  226.           while (*cp >= '0' && *cp <= '9')
  227.         ifunit = ifunit * 10 + *cp++ - '0';
  228.  
  229.           if (s->args->a_unit == NULL && ifunit != unit) {
  230.         continue;
  231.           }
  232.           s->unit = ifunit;
  233.         } else {
  234.           /* an interface sans unit number, eg. "slip" */
  235.           s->unit = unit - (s->args->a_unit ? *s->args->a_unit : 0);
  236.         }
  237.         *cp = '\0';
  238.         ssc = s;
  239.         break;
  240.       }
  241.     }
  242. #endif
  243.     ssconfig_free(s);
  244.     continue;
  245.       }
  246.       break;
  247.     } 
  248.     SelectInput(oldinfh);
  249.   } else {
  250.     if (buf)
  251.       ioerr = IoErr();
  252.     else
  253.       ioerr = ERROR_NO_FREE_STORE;
  254.   }
  255.  
  256.   if (iffh) Close(iffh);
  257.   if (buf) FreeVec(buf);
  258.  
  259.   if (ioerr) {
  260.     if (ssc)
  261.       ssconfig_free(ssc);
  262.     if (ssc_generic)
  263.       ssconfig_free(ssc_generic);
  264.     ssc_generic = ssc = NULL;
  265.   } 
  266.  
  267.   if (ssc == NULL) {
  268.     ssc = ssc_generic;
  269.   } else {
  270.     if (ssc && ssc_generic)
  271.       ssconfig_free(ssc_generic);
  272.     ssc_generic = NULL;
  273.   }
  274.  
  275.   if (ssc) {
  276.     if (ssc->args->a_unit) {
  277.       if (ssc_generic)
  278.     *ssc->args->a_unit += unit;
  279.     } else {
  280.       ssc->args->a_unit = &ssc->unit;
  281.     }
  282.  
  283.     strcpy(ssc->name, devname);
  284.   }
  285.  
  286.   return ssc;
  287. }
  288.  
  289. /*
  290.  * Default configuration as per hardware type
  291.  */
  292. static const struct wire_defaults {
  293.   LONG  wd_wiretype;
  294.   LONG  wd_iptype;        /* IP packet type */
  295.   WORD  wd_ipno;        /* SANA-II requests reserved for receiving */
  296.   WORD  wd_writeno;        /* SANA-II requests reserved for sending */
  297.   LONG  wd_arptype;        /* ARP packet type */
  298.   WORD  wd_arpno;        /* SANA-II requests reserved for ARP */
  299.   WORD  wd_arphdr;        /* ARP version */
  300.   WORD  wd_ifflags;        /* Interface flags */
  301.   BYTE  wd_pad[2];
  302. } wire_defaults[] = {
  303.   { 
  304.     S2WireType_Ethernet, 
  305.     ETHERTYPE_IP, 16, 16, 
  306.     ETHERTYPE_ARP, 4, 1, 
  307.     IFF_NOTRAILERS|IFF_BROADCAST|IFF_SIMPLEX, 
  308.   },
  309.   { 
  310.     S2WireType_Arcnet, 
  311.     ARCOTYPE_IP, 16, 16, 
  312.     ARCOTYPE_ARP, 4, 7, 
  313.     IFF_NOTRAILERS|IFF_BROADCAST|IFF_SIMPLEX, 
  314.   },
  315.   { 
  316.     S2WireType_SLIP, 
  317.     SLIPTYPE_IP, 8, 8,
  318.     0, 0, 0,
  319.     IFF_NOTRAILERS|IFF_POINTOPOINT|IFF_NOARP, 
  320.   },
  321.   { 
  322.     S2WireType_CSLIP, 
  323.     SLIPTYPE_IP, 8, 8,
  324.     0, 0, 0,
  325.     IFF_NOTRAILERS|IFF_POINTOPOINT|IFF_NOARP, 
  326.   },
  327.   { 
  328.     S2WireType_PPP, 
  329.     PPPTYPE_IP, 8, 8,
  330.     0, 0, 0,
  331.     IFF_NOTRAILERS|IFF_POINTOPOINT|IFF_NOARP, 
  332.   },
  333.   /* Use ethernet as default */
  334.   {
  335.     0,
  336.     ETHERTYPE_IP, 16, 16,
  337.     ETHERTYPE_ARP, 4, 1,
  338.     IFF_NOTRAILERS|IFF_BROADCAST|IFF_SIMPLEX, 
  339.   },
  340. };
  341.  
  342. /*
  343.  * Initialize sana_softc
  344.  */
  345. void
  346. ssconfig(struct sana_softc *ifp, struct ssconfig *ifc)
  347. {
  348.   const struct ssc_args *args = ifc->args;
  349.   const struct wire_defaults *wd;
  350.   LONG wt = ifp->ss_hwtype;
  351.   LONG reqtotal = 0;
  352.  
  353.   assert(ifp != NULL);
  354.   assert(ifp->ss_if.if_type == IFT_SANA);
  355.  
  356.   for (wd = wire_defaults; wd->wd_wiretype != 0; wd++) {
  357.     if (wt == wd->wd_wiretype)
  358.       break;
  359.   }
  360.   
  361.   ifp->ss_ip.type = args->a_iptype ? *args->a_iptype : wd->wd_iptype;
  362.   reqtotal += ifp->ss_ip.reqno = args->a_ipno ? *args->a_ipno : wd->wd_ipno;
  363.  
  364.   ifp->ss_arp.type = args->a_arptype ? *args->a_arptype : wd->wd_arptype;
  365.   reqtotal += ifp->ss_arp.reqno = args->a_arpno ? *args->a_arpno : wd->wd_arpno;
  366.   ifp->ss_arp.hrd = args->a_arphdr ? *args->a_arphdr : wd->wd_arphdr;
  367.  
  368.   reqtotal += args->a_writeno ? *args->a_writeno : wd->wd_writeno;
  369.  
  370.   if (reqtotal > 65535)
  371.     reqtotal = 65535;
  372.   ifp->ss_reqno = reqtotal;
  373.  
  374.   {
  375.     UWORD ifflags = wd->wd_ifflags;
  376.  
  377.     if (args->a_noarp)
  378.       ifflags |= IFF_NOARP;
  379.     if (args->a_point2point) {
  380.       ifflags |= IFF_POINTOPOINT;
  381.       ifflags &= ~IFF_BROADCAST;
  382.     }
  383.     if (args->a_nosimplex)
  384.       ifflags &= ~IFF_SIMPLEX;
  385.     if (args->a_loopback)
  386.       ifflags |= IFF_LOOPBACK;
  387.  
  388.     ifp->ss_if.if_flags = ifflags;
  389.   }
  390.  
  391.   /* Flags for soft_sanac */
  392.   ifp->ss_cflags = SS_CFLAGS;
  393.  
  394.   if (args->a_notrack)
  395.     ifp->ss_cflags &= ~(SSF_TRACK);
  396.  
  397.   /* Set up name */
  398.   ifp->ss_if.if_name = strcpy(ifp->ss_name, ifc->name);
  399.   ifp->ss_if.if_unit = ifc->unit;
  400.   ifp->ss_execname = strcpy((char *)(ifp + 1), ifc->args->a_dev);
  401.   ifp->ss_execunit = *ifc->args->a_unit;
  402. }
  403.  
  404.